package com.un.ebs.sys.service.impl;

import com.un.ebs.sys.service.RedisService;
import org.redisson.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class RedisServiceImpl implements RedisService {

    @Autowired
    RedissonClient redissonClient;


    @Override
    public Map<String, Double> getBalanceMap(String key) {
        Iterator<String> iterator = redissonClient.getKeys().getKeysByPattern(key + ":" + "*").iterator();
        Map<String, Double> map = new HashMap<>();
        while (iterator.hasNext()) {
            String next = iterator.next();
            Double atomicDouble = getAtomicDouble(next);
            map.put(next, atomicDouble);
        }
        return map;
    }

    @Override
    public Long getAtomicLong(String key) {
        RAtomicLong rAtomicLong = redissonClient.getAtomicLong(key);
        return rAtomicLong.get();
    }

    @Override
    public Long setAtomicLong(String key, Long value, Long sec) {
        RAtomicLong rAtomicLong = redissonClient.getAtomicLong(key);
        rAtomicLong.set(value);
        return value;
    }

    @Override
    public Long incAtomicLong(String key, Long value, Long sec) {
        RAtomicLong rAtomicLong = redissonClient.getAtomicLong(key);
        return rAtomicLong.addAndGet(value);
    }

    @Override
    public Long decAtomicLong(String key, Long value, Long sec) {
        return this.incAtomicLong(key, value * -1, sec);
    }

    @Override
    public Double getAtomicDouble(String key) {
        RAtomicDouble rAtomicDouble = redissonClient.getAtomicDouble(key);
        return rAtomicDouble.get();
    }

    @Override
    public Double setAtomicDouble(String key, Double value, Long sec) {
        RAtomicDouble rAtomicDouble = redissonClient.getAtomicDouble(key);
        rAtomicDouble.set(value);
        return value;
    }

    @Override
    public Double incAtomicDouble(String key, Double value, Long sec) {
        RAtomicDouble rAtomicDouble = redissonClient.getAtomicDouble(key);
        return rAtomicDouble.addAndGet(value);
    }

    @Override
    public Double decAtomicDouble(String key, Double value, Long sec) {
        return this.incAtomicDouble(key, value * -1, sec);
    }

    @Override
    public RLock getLock(String key) {
        return redissonClient.getLock(key);
    }

    @Override
    public <T> void set(String key, T value, Long sec) {
        RBucket<T> bucket = redissonClient.getBucket(key);
        if (sec != 0) {
            bucket.set(value, sec, TimeUnit.SECONDS);
        } else {
            bucket.set(value);
        }
    }

    @Override
    public <T> T get(String key) {
        RBucket<T> bucket = redissonClient.getBucket(key);
        return bucket.get();
    }

    @Override
    public void remove(String key) {
        redissonClient.getBucket(key).delete();
    }

    @Override
    public <T> void hSet(String key, String hashKey, T hashValue) {
        RMap<String, T> map = redissonClient.getMap(key);
        map.put(hashKey, hashValue);
    }

    @Override
    public <T> T hGet(String key, String hashKey) {
        RMap<String, T> map = redissonClient.getMap(key);
        return map.get(hashKey);
    }

    @Override
    public <T> Map<String, T> hGet(String key) {
        RMap<String, T> map = redissonClient.getMap(key);
        return map;
    }

    @Override
    public <T> boolean hasKey(String key, T value) {
        RMap<String, T> map = redissonClient.getMap(key);
        return map.get(key) == value;

    }
}
